<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
	UploadFilled,
	Download,
	Loading,
	DataAnalysis,
	Delete,
	Document,
	ArrowDown,
} from '@element-plus/icons-vue'
import {
	downloadExampleFile,
	getExampleFileContent,
	getFileList,
	postUploadFile, // 上传文件
	postFileContent, // 获取文件内容
} from '@/api/product/machineLearning'

const { t } = useI18n()

const props = defineProps({
	modelValue: {
		type: Object,
		default: () => ({
			uploadedFile: null,
			fileData: [],
			fileName: '', // 服务器返回的文件名，用于接口传参
			originalName: '', // 用户上传的原始文件名，用于显示
		}),
	},
})

const formRef = ref(null)
const uploadRef = ref(null)
const emit = defineEmits(['update:modelValue'])

const uploadFileList = ref([])

// 响应式数据
const isAnalyzing = ref(false)
const isDownloading = ref(false)
const tableData = ref([])
const tableColumns = ref([])
const analysisResult = ref(null)

// 添加当前文件状态 - 用于高亮显示
const currentDisplayName = ref('') // 显示的文件名（originalName）

// 示例文件配置
const exampleFiles = {
	分类: {
		fileName: 'EHEA_class.csv',
		displayName: 'EHEA分类示例文件',
		description: '适用于分类（分类算法）',
	},
	回归: {
		fileName: 'HV_regress.csv',
		displayName: 'HV回归示例文件',
		description: '适用于回归（回归算法）',
	},
}

const rules = ref({
	uploadedFile: [
		{
			validator: (rule, value, callback) => {
				// 检查是否有数据（通过analysisResult判断是否加载了数据）
				if (
					!analysisResult.value ||
					!props.modelValue.fileName ||
					props.modelValue.fileName.trim() === ''
				) {
					callback(new Error('请上传CSV文件或选择云服务器文件'))
				} else {
					callback()
				}
			},
			trigger: 'blur', // 改为blur触发，避免频繁触发
		},
	],
})

// 更新 modelValue
const updateModelValue = (updates) => {
	const newValue = { ...props.modelValue, ...updates }
	emit('update:modelValue', newValue)
}

// 显示 CSV 预览
const displayPreview = (data) => {
	try {
		const rows = data.split('\n').filter((row) => row.trim() !== '')
		if (rows.length === 0) {
			ElMessage.warning('文件为空')
			return
		}

		// 自动判断分隔符：优先逗号，否则空格
		const delimiter = rows[0].includes(',') ? ',' : /\s+/
		const headers = rows[0]
			.trim()
			.split(delimiter)
			.map((col) => col.trim())
		if (headers.length === 0) {
			ElMessage.warning('文件格式不正确')
			return
		}

		// 设置表格列
		tableColumns.value = headers.map((header) => ({
			prop: header,
			label: header,
			width: 'auto',
		}))

		// 设置表格数据（排除表头，显示所有数据行）
		const dataRows = rows.slice(1)
		tableData.value = dataRows.map((row) => {
			const cols = row.trim().split(delimiter)
			const rowData = {}
			headers.forEach((header, index) => {
				rowData[header] = cols[index] ? cols[index].trim() : ''
			})
			return rowData
		})

		props.modelValue.tableData = tableData.value
		props.modelValue.tableColumns = tableColumns.value
		props.modelValue.targetFeatureTable = tableColumns.value.map((item) => {
			return {
				name: item.label,
				isFeature: false,
				isTarget: item.label === 'phase' ? true : false,
			}
		})

		// 分析数据统计信息
		analyzeData(rows, headers, delimiter)
	} catch (error) {
		console.error('解析文件失败:', error)
		ElMessage.error('解析文件失败，请检查文件格式')
	}
}

// 分析数据统计信息
const analyzeData = (rows, headers, delimiter) => {
	const dataRows = rows.slice(1)
	const totalRows = dataRows.length
	const totalColumns = headers.length

	// 计算每列的数据类型和基本统计
	const columnAnalysis = headers.map((header) => {
		const columnIndex = headers.indexOf(header)
		const values = dataRows
			.map((row) => {
				const cols = row.trim().split(delimiter)
				return cols[columnIndex] ? cols[columnIndex].trim() : ''
			})
			.filter((val) => val !== '')

		const numericValues = values.filter(
			(val) => !isNaN(parseFloat(val)) && val !== ''
		)
		const isNumeric = numericValues.length > values.length * 0.8 // 80%以上是数字才认为是数值型

		return {
			column: header,
			totalValues: values.length,
			missingValues: totalRows - values.length,
			dataType: isNumeric ? '数值型' : '文本型',
			uniqueValues: new Set(values).size,
			...(isNumeric && numericValues.length > 0
				? {
						min: Math.min(...numericValues.map((v) => parseFloat(v))),
						max: Math.max(...numericValues.map((v) => parseFloat(v))),
						avg:
							numericValues.reduce((sum, v) => sum + parseFloat(v), 0) /
							numericValues.length,
					}
				: {}),
		}
	})

	analysisResult.value = {
		totalRows,
		totalColumns,
		columnAnalysis,
	}
}

// 处理文件上传
const handleFileUpload = async (file) => {
	if (file.type === 'text/csv' || file.name.endsWith('.csv')) {
		isAnalyzing.value = true

		// 上传到服务器
		const formData = new FormData()
		formData.append('file', file)
		let serverFileName = file.name // 默认使用本地文件名
		const originalFileName = file.name // 保存原始文件名用于显示

		try {
			const uploadResult = await postUploadFile(formData)
			if (uploadResult && uploadResult.data && uploadResult.data.file_name) {
				// 使用服务器返回的文件名
				serverFileName = uploadResult.data.file_name
			}
			ElMessage.success('文件上传成功')
			await getFileListFn() // 刷新服务器文件列表
		} catch (e) {
			ElMessage.error('文件上传失败')
			isAnalyzing.value = false
			return false
		}

		// 本地预览
		const reader = new FileReader()
		reader.onload = (e) => {
			try {
				displayPreview(e.target.result)
				updateModelValue({
					uploadedFile: file,
					fileName: serverFileName, // 服务器文件名，用于接口传参
					originalName: originalFileName, // 原始文件名，用于显示
					fileData: e.target.result,
				})
				// 设置当前显示文件名用于高亮
				currentDisplayName.value = originalFileName

				// 手动触发表单验证更新
				nextTick(() => {
					if (formRef.value) {
						formRef.value.validateField('uploadedFile')
					}
				})
			} catch (error) {
				console.error('处理文件失败:', error)
				ElMessage.error('处理文件失败')
			} finally {
				isAnalyzing.value = false
			}
		}

		reader.onerror = () => {
			ElMessage.error('读取文件失败')
			isAnalyzing.value = false
		}

		reader.readAsText(file)
		return true
	} else {
		ElMessage.error('请上传 CSV 文件')
		return false
	}
}

// 处理文件选择变化
const handleFileChange = async (uploadFile, uploadFiles) => {
	// 清除旧数据
	clearOldData()

	// 获取原始文件对象
	const file = uploadFile.raw || uploadFile

	if (file) {
		await handleFileUpload(file)
		// 触发表单验证更新
		if (formRef.value) {
			formRef.value.validateField('uploadedFile')
		}
	}
}

const getFileListFn = async () => {
	const res = await getFileList()
	uploadFileList.value = res.data || []
}

// 选择服务器文件
const selectServerFile = async (fileItem) => {
	try {
		isAnalyzing.value = true
		isCloudLoading.value = true // 只用于右侧预览区加载动画

		// 获取服务器文件内容（纯文本）
		const { data } = await postFileContent({
			file_name: fileItem.fileName,
		})

		// 清除旧数据
		clearOldData()

		// 处理文件数据
		displayPreview(data.fileContent)
		updateModelValue({
			uploadedFile: null, // 服务器文件不是上传的文件
			fileName: fileItem.fileName, // 服务器文件名，用于接口传参
			originalName: fileItem.originalName || fileItem.fileName, // 显示名称，优先使用originalName
			fileData: data.fileContent,
		})

		// 设置当前显示文件名用于高亮
		currentDisplayName.value = fileItem.originalName || fileItem.fileName

		// 手动触发表单验证更新
		nextTick(() => {
			if (formRef.value) {
				formRef.value.validateField('uploadedFile')
			}
		})

		ElMessage.success(
			`已选择服务器文件: ${fileItem.originalName || fileItem.fileName}`
		)
	} catch (error) {
		console.error('加载服务器文件失败:', error)
		ElMessage.error('加载服务器文件失败')
	} finally {
		isAnalyzing.value = false
		isCloudLoading.value = false
	}
}

// 新增：云文件加载状态
const isCloudLoading = ref(false)

// 清除旧数据
const clearOldData = () => {
	// 清空表格数据
	tableData.value = []
	tableColumns.value = []
	analysisResult.value = null

	// 清空当前显示文件名
	currentDisplayName.value = ''

	// 清空表单数据
	updateModelValue({
		uploadedFile: null,
		fileName: '',
		originalName: '',
		fileData: '',
		tableColumns: [],
		tableData: [],
		targetFeatureTable: [], // 也清空目标特征表
	})

	// 重置上传组件
	if (uploadRef.value) {
		uploadRef.value.clearFiles()
	}

	// 触发表单验证更新
	nextTick(() => {
		if (formRef.value) {
			formRef.value.validateField('uploadedFile')
		}
	})
}

// 下载示例文件
const downloadExample = async (algorithmType = null) => {
	if (isDownloading.value) return

	// 如果没有指定算法类型，显示选择对话框
	if (!algorithmType) {
		try {
			const { value } = await ElMessageBox.prompt(
				'请选择要下载的示例文件类型：',
				'下载示例文件',
				{
					confirmButtonText: '下载',
					cancelButtonText: '取消',
					inputType: 'select',
					inputOptions: [
						{ value: '分类', label: 'EHEA分类示例 (分类)' },
						{ value: '回归', label: 'HV回归示例 (回归)' },
					],
					inputPlaceholder: '请选择示例文件类型',
					inputValidator: (value) => {
						if (!value) {
							return '请选择一个示例文件类型'
						}
					},
				}
			)
			algorithmType = value
		} catch {
			// 用户取消操作
			return
		}
	}

	const fileConfig = exampleFiles[algorithmType]
	if (!fileConfig) {
		ElMessage.error('未找到对应的示例文件')
		return
	}

	isDownloading.value = true
	try {
		const blob = await downloadExampleFile(fileConfig.fileName)
		const link = document.createElement('a')
		link.href = URL.createObjectURL(blob)
		link.download = fileConfig.fileName
		document.body.appendChild(link)
		link.click()
		setTimeout(() => {
			document.body.removeChild(link)
			URL.revokeObjectURL(link.href)
		}, 100)
		ElMessage.success(`${fileConfig.displayName}下载成功`)
	} catch (error) {
		console.error('下载失败:', error)
		ElMessage.error('下载失败，请检查文件路径')
	} finally {
		isDownloading.value = false
	}
}

// 移除初始化示例预览函数
// const initExamplePreview = async () => { ... }

const verification = async () => {
	try {
		console.log('DataSource verification:', {
			analysisResult: analysisResult.value,
			fileName: props.modelValue.fileName,
			hasData: !!analysisResult.value && !!props.modelValue.fileName,
		})
		await formRef.value.validate()
		return true
	} catch (e) {
		console.log('DataSource verification failed:', e)
		ElMessage.error('请上传CSV文件或选择云服务器文件')
		return false
	}
}

onMounted(() => {
	nextTick(() => {
		// 获取文件列表
		getFileListFn()

		// 恢复之前的数据状态
		restoreDataFromProps()
	})
})

// 新增：从props恢复数据状态
const restoreDataFromProps = () => {
	console.log('恢复数据状态:', props.modelValue)

	// 如果有文件名和表格数据，恢复显示状态
	if (
		props.modelValue.fileName &&
		props.modelValue.tableData &&
		props.modelValue.tableData.length > 0
	) {
		// 恢复表格数据
		tableData.value = [...props.modelValue.tableData]
		tableColumns.value = [...props.modelValue.tableColumns]

		// 恢复当前显示文件名用于高亮
		currentDisplayName.value =
			props.modelValue.originalName || props.modelValue.fileName

		// 重新生成分析结果
		if (props.modelValue.fileData) {
			const rows = props.modelValue.fileData
				.split('\n')
				.filter((row) => row.trim() !== '')
			if (rows.length > 0) {
				const delimiter = rows[0].includes(',') ? ',' : /\s+/
				const headers = rows[0]
					.trim()
					.split(delimiter)
					.map((col) => col.trim())
				analyzeData(rows, headers, delimiter)
			}
		}

		console.log('数据恢复完成:', {
			tableDataLength: tableData.value.length,
			tableColumnsLength: tableColumns.value.length,
			currentDisplayName: currentDisplayName.value,
		})
	}
}

defineExpose({
	verification,
})
</script>

<template>
	<div class="component DataSource">
		<div class="component-header">
			<div class="component-header-title">选择数据源</div>
		</div>
		<div class="DataSource-content">
			<div class="left-panel">
				<!-- 左上：文件上传区域 -->
				<div class="upload-section">
					<h3 class="section-title">
						<el-icon><upload-filled /></el-icon>
						上传文件
					</h3>
					<el-form ref="formRef" :model="modelValue" :rules="rules">
						<el-form-item prop="uploadedFile">
							<el-upload
								ref="uploadRef"
								drag
								:auto-upload="false"
								:show-file-list="true"
								accept=".csv"
								@change="handleFileChange"
								class="upload-container"
							>
								<el-icon class="el-icon--upload"><upload-filled /></el-icon>
								<div class="el-upload__text">
									将文件拖到此处，或<em>点击上传</em>
								</div>
								<template #tip>
									<div class="upload-tip-wrapper">
										<div class="el-upload__tip">只能上传 csv 文件</div>
										<el-dropdown @command="downloadExample" trigger="click">
											<el-button
												:loading="isDownloading"
												size="small"
												type="primary"
												link
											>
												<el-icon><download /></el-icon>
												下载示例文件
												<el-icon class="el-icon--right">
													<arrow-down />
												</el-icon>
											</el-button>
											<template #dropdown>
												<el-dropdown-menu>
													<el-dropdown-item command="分类">
														EHEA分类示例 (分类)
													</el-dropdown-item>
													<el-dropdown-item command="回归">
														HV回归示例 (回归)
													</el-dropdown-item>
												</el-dropdown-menu>
											</template>
										</el-dropdown>
									</div>
								</template>
							</el-upload>
						</el-form-item>
					</el-form>
				</div>

				<!-- 左下：服务器文件列表 -->
				<div class="server-files-section">
					<h3 class="section-title">
						<el-icon><data-analysis /></el-icon>
						服务器文件
					</h3>
					<div class="server-files-container">
						<div v-if="uploadFileList.length === 0" class="empty-files">
							<el-empty description="暂无服务器文件" :image-size="60" />
						</div>
						<div v-else class="files-list">
							<div
								v-for="item in uploadFileList"
								:key="item.id"
								class="file-item"
								:class="{
									active: props.modelValue.fileName === item.fileName,
								}"
								@click="selectServerFile(item)"
							>
								<el-icon class="file-icon"><Document /></el-icon>
								<span class="file-name">{{
									item.originalName || item.fileName
								}}</span>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 右边：数据预览和分析结果 -->
			<div class="right-panel">
				<h3 class="section-title">
					<el-icon><data-analysis /></el-icon>
					数据预览
				</h3>
				<div
					class="preview-container"
					v-loading="isCloudLoading"
					element-loading-text="正在加载云文件..."
				>
					<div v-if="isAnalyzing" class="loading-container">
						<el-icon class="is-loading"><loading /></el-icon>
						<p>正在分析上传的文件...</p>
					</div>
					<div v-else-if="tableData.length > 0" class="data-preview">
						<!-- 数据统计信息 -->
						<div v-if="analysisResult" class="analysis-summary">
							<el-card shadow="never" class="analysis-card">
								<template #header>
									<div class="analysis-header">
										<el-icon><data-analysis /></el-icon>
										<span>数据统计</span>
									</div>
								</template>
								<div class="analysis-content">
									<div class="analysis-basic">
										<div class="analysis-item">
											<span class="label">总行数:</span>
											<span class="value">{{ analysisResult.totalRows }}</span>
										</div>
										<div class="analysis-item">
											<span class="label">总列数:</span>
											<span class="value">{{
												analysisResult.totalColumns
											}}</span>
										</div>
										<div class="analysis-item">
											<span class="label">文件名:</span>
											<span class="value">{{ modelValue.originalName }}</span>
										</div>
									</div>
								</div>
							</el-card>
						</div>

						<!-- 数据表格 -->
						<div class="table-wrapper">
							<el-table
								:data="tableData"
								border
								stripe
								max-height="340"
								style="width: 100%"
								:scrollbar-always-on="true"
							>
								<el-table-column
									v-for="column in tableColumns"
									:key="column.prop"
									:prop="column.prop"
									:label="column.label"
									min-width="120"
									show-overflow-tooltip
								/>
							</el-table>
						</div>
					</div>
					<div v-else class="empty-preview">
						<el-empty description="请上传CSV文件或选择云服务器文件以预览数据" />
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<style scoped lang="scss">
@import url('./index.scss');

.DataSource {
	&-content {
		padding: 20px;
		box-sizing: border-box;
		display: flex;
		gap: 20px;

		.left-panel {
			display: flex;
			flex-direction: column;
			gap: 20px;
			flex: 1;

			.upload-section {
				:deep(.el-form-item) {
					margin: 0 !important;
				}
				.section-title {
					display: flex;
					align-items: center;
					gap: 8px;
					font-weight: 500;
					margin-bottom: 15px;
					color: #303133;
					font-size: 16px;
				}

				.upload-container {
					width: 100%;

					:deep(.el-upload) {
						width: 100%;

						.el-upload-dragger {
							width: 100%;
							height: 180px;
							border: 2px dashed #d9d9d9;
							border-radius: 6px;
							cursor: pointer;
							position: relative;
							overflow: hidden;
							transition: border-color 0.2s ease;

							&:hover {
								border-color: #409eff;
							}
						}
					}

					.upload-tip-wrapper {
						display: flex;
						align-items: center;
						justify-content: space-between;
						margin-top: 10px;

						.el-upload__tip {
							color: #606266;
							font-size: 12px;
						}
					}
				}

				.el-upload-list {
					margin: 0 !important;
					.el-upload-list__item-info {
						margin: 0 !important;
						.el-upload-list__item-name {
							padding: 0 !important;
						}
					}
				}
			}

			.server-files-section {
				.section-title {
					display: flex;
					align-items: center;
					gap: 8px;
					font-weight: 500;
					margin-bottom: 15px;
					color: #303133;
					font-size: 16px;
				}

				.server-files-container {
					border: 1px solid #ebeef5;
					border-radius: 4px;
					padding: 10px;
					height: 230px;
					overflow-y: auto;
					background-color: #f9fafc;

					.empty-files {
						display: flex;
						justify-content: center;
						align-items: center;
						height: 100%;
					}

					.files-list {
						display: flex;
						flex-direction: column;
						gap: 8px;

						.file-item {
							display: flex;
							align-items: center;
							gap: 10px;
							padding: 8px 12px;
							border: 1px solid #ebeef5;
							border-radius: 4px;
							background-color: #fff;
							cursor: pointer;
							transition: background-color 0.2s ease;

							&:hover {
								background-color: #f5f7fa;
							}

							.file-icon {
								font-size: 18px;
								color: #409eff;
							}

							.file-name {
								flex-grow: 1;
								overflow: hidden;
								text-overflow: ellipsis;
								white-space: nowrap;
								font-size: 14px;
								color: #303133;
							}

							.el-tag {
								margin-left: 10px;
							}
						}
					}
				}
			}
		}

		.right-panel {
			display: flex;
			flex-direction: column;
			width: 1200px;
			.section-title {
				display: flex;
				align-items: center;
				gap: 8px;
				font-weight: 500;
				margin-bottom: 15px;
				color: #303133;
				font-size: 16px;
			}

			.preview-container {
				border: 1px solid #ebeef5;
				border-radius: 4px;
				padding: 20px;
				background-color: #f9fafc;
				height: 100%;
				display: flex;
				flex-direction: column;
				gap: 20px;

				.loading-container {
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					padding: 40px;
					color: #909399;

					.el-icon {
						font-size: 24px;
						margin-bottom: 10px;
					}
				}

				.data-preview {
					flex-grow: 1;
					display: flex;
					flex-direction: column;
					gap: 20px;

					.analysis-summary {
						.analysis-card {
							.analysis-header {
								display: flex;
								align-items: center;
								gap: 8px;
								font-weight: 500;
							}

							.analysis-content {
								.analysis-basic {
									display: flex;
									gap: 20px;
									margin-bottom: 16px;
									padding-bottom: 12px;
									border-bottom: 1px solid #f0f0f0;

									.analysis-item {
										.label {
											color: #606266;
											margin-right: 8px;
										}
										.value {
											font-weight: 500;
											color: #409eff;
										}
									}
								}

								.analysis-columns {
									display: grid;
									grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
									gap: 12px;

									.column-analysis {
										padding: 12px;
										border: 1px solid #e4e7ed;
										border-radius: 6px;
										background-color: #fafafa;

										.column-header {
											display: flex;
											justify-content: space-between;
											align-items: center;
											margin-bottom: 8px;

											.column-name {
												font-weight: 500;
												color: #303133;
											}
										}

										.column-stats {
											display: flex;
											flex-direction: column;
											gap: 4px;
											font-size: 12px;
											color: #606266;

											span {
												display: inline-block;
												margin-right: 12px;
											}
										}
									}
								}
							}
						}

						.table-wrapper {
							.table-header {
								margin-bottom: 12px;

								h4 {
									margin: 0;
									color: #303133;
									font-size: 14px;
									font-weight: 500;
								}
							}

							.table-footer {
								margin-top: 10px;
								text-align: right;
							}
						}
					}

					.empty-preview {
						padding: 40px;
						text-align: center;
						display: flex;
						flex-direction: column;
						align-items: center;
						gap: 20px;

						.el-empty {
							margin-bottom: 0;
						}

						.example-buttons {
							display: flex;
							flex-direction: column;
							align-items: center;
							gap: 16px;

							.el-button {
								width: 200px;
							}

							.example-tips {
								color: #606266;
								font-size: 12px;
								text-align: left;

								p {
									margin: 4px 0;
									line-height: 1.4;
								}
							}
						}
					}
				}
			}
		}
	}
}

.active {
	border: 1px solid #409eff !important;
}
</style>
